mod ai_source;
mod ai_target;
mod ai_target_type;
mod ai_task;

use crate::ai_source::AiSource;
use crate::ai_target::AiTarget;
use crate::ai_target_type::AiTargetType;
use crate::ai_task::AiTask;
use common_service::db_helper;
use std::path::PathBuf;

//#[async_trait::async_trait] 是 Rust 中 async_trait crate 提供的宏，用来在 trait 中支持异步函数（async fn）的实现。
#[async_trait::async_trait]
trait FileRecord {
    fn url(&self) -> &str;
    async fn delete(&self, pool: &sqlx::MySqlPool) -> sqlx::Result<u64>;
}

// 为 AiSource 实现 FileRecord trait
#[async_trait::async_trait]
impl FileRecord for AiSource {
    fn url(&self) -> &str {
        &self.url
    }
    async fn delete(&self, pool: &sqlx::MySqlPool) -> sqlx::Result<u64> {
        self.delete(pool).await
    }
}

// 为 AiTarget 实现 FileRecord trait
#[async_trait::async_trait]
impl FileRecord for AiTarget {
    fn url(&self) -> &str {
        &self.url
    }
    async fn delete(&self, pool: &sqlx::MySqlPool) -> sqlx::Result<u64> {
        self.delete(pool).await
    }
}

// 为 AiTargetType 实现 FileRecord trait
#[async_trait::async_trait]
impl FileRecord for AiTargetType {
    fn url(&self) -> &str {
        &self.head_img
    }
    async fn delete(&self, pool: &sqlx::MySqlPool) -> sqlx::Result<u64> {
        self.delete(pool).await
    }
}

// 通用清理函数：删除 url 为空或文件不存在的记录
async fn clean_invalid_files<T>(
    pool: &sqlx::MySqlPool,
    root_dir: &str,
    items: Vec<T>,
) -> sqlx::Result<()>
where
    T: FileRecord + Send,
{
    for item in items {
        let url = item.url();
        // 如果 url 为空，直接删除记录
        if url.is_empty() {
            item.delete(pool).await?;
            continue;
        }

        // 拼接 root_dir 和 url 构成完整路径
        let mut file_path = PathBuf::from(root_dir);
        file_path.push(url);

        // 文件不存在，也删除记录
        if !file_path.exists() {
            item.delete(pool).await?;
        }
    }
    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化数据库连接池  3306测试
    //db_helper::init_pool("mysql://root:sushaokun%40no1@172.18.0.240:10003/aicomic").await?;
    db_helper::init_pool("mysql://root:sushaokun%40no1@172.18.0.240:3306/aicomic").await?;
    let pool = db_helper::try_get_pool().ok_or("数据库连接池未初始化")?;
    let root_dir = "Z:";

    // 获取所有 AiSource
    let sources_list = AiSource::query_list(&pool).await?;
    clean_invalid_files(&pool, root_dir, sources_list.clone()).await?;

    // 获取所有 AiTarget
    let targets_list = AiTarget::query_list(&pool).await?;
    clean_invalid_files(&pool, root_dir, targets_list.clone()).await?;

    // 获取所有 AiTargetType
    let target_types_list = AiTargetType::query_list(&pool).await?;
    clean_invalid_files(&pool, root_dir, target_types_list.clone()).await?;

    // 再次查询
    let sources_list = AiSource::query_list(&pool).await?;
    let targets_list = AiTarget::query_list(&pool).await?;
    // 收集有效的 source_id 和 target_id
    let sources_ids: Vec<u32> = sources_list.iter().filter_map(|s| s.id).collect();
    let targets_ids: Vec<u32> = targets_list.iter().filter_map(|t| t.id).collect();
    // 查询所有 AiTask
    let tasks_list = AiTask::query_list(&pool).await?;
    for task in tasks_list {
        // 如果 source_id 或 target_id 不存在，或者不在有效 id 列表中，就删除
        let delete = match (task.source_id, task.target_id) {
            (Some(sid), Some(tid)) => !sources_ids.contains(&sid) || !targets_ids.contains(&tid),
            _ => true, // source_id 或 target_id 为 None
        };
        if delete {
            task.delete(&pool).await?;
        }
    }

    Ok(())
}
